package br.com.diego.system.view.action;

import java.io.InputStream;
import java.util.Collection;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRMapCollectionDataSource;
import net.sf.jasperreports.engine.util.JRLoader;
import org.springframework.util.Assert;


public abstract class AbstractReportAction extends AbstractDiegoAction {

    private static final long serialVersionUID = 1L;

    public abstract JasperPrint createReport();
    private static Map<String, JasperReport> jrCache = new HashMap<String, JasperReport>();

    protected JasperPrint createReport(final String resourceName, final Collection<Map<String, ?>> values) {
        return createReport(resourceName, new HashMap<String, Object>(), values);
    }

    protected JasperPrint createReport(String resourceName,
            Map<String, Object> parameters, Collection<Map<String, ?>> values) {

        parameters.put("REPORT_LOCALE", new Locale("pt", "BR"));

        JasperReport jasperReport = jrCache.get(resourceName);

        if (jasperReport == null) {
            InputStream is = AbstractReportAction.class.getResourceAsStream(resourceName);

            if (is == null) {
                throw new IllegalArgumentException(String.format("Não foi possível localizar o relatório. (%s)", resourceName));
            } else {
                try {
                    jasperReport = (JasperReport) JRLoader.loadObject(is);
                } catch (JRException e) {
                    throw new IllegalArgumentException(String.format("Erro ao carregar o relatório. (%s)", resourceName));
                }
                jrCache.put(resourceName, jasperReport);
            }
        }

        Assert.notNull(jasperReport);
        Assert.notNull(parameters);
        Assert.notNull(values);
        Assert.notEmpty(values, "Não existe registros para esta consulta.");

        try {
            return JasperFillManager.fillReport(jasperReport, parameters,
                    new JRMapCollectionDataSource(values));
        } catch (Exception e) {
            e.printStackTrace();
            throw new IllegalArgumentException(String.format("Não foi possível preencher o relatório. (%s)", resourceName));
        }
    }
}
